<template>
  <div style="height: 100%;position: relative;">
    <div class="bim-operation">
      <el-input v-model="viewToken" @keyup.enter.native="viewTokenInput" size="mini" clearable placeholder="输入模型 viewToken" style="width: 300px;margin-right: 10px;" />
      <header-select @selectProject="getProject" />
      <el-select v-model="buildingId" size="mini" style="margin-left: 10px;" placeholder="请选择" @change="selectBuilding">
        <el-option
          v-for="item in buildings"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <!--<el-select v-model="floorName" class="custom-select" placeholder="请选择楼层" style="width: 200px;" clearable size="mini" @change="floorChange">
        <el-option
          class="custom-option"
          v-for="item in floorList"
          :key="item.id"
          :label="item.name"
          :value="item.name"
        />
      </el-select>-->
      <!--<el-button type="primary" size="mini" style="margin-left: 10px" @click="switchModel" v-show="floorViewTokens.length > 1">切换模型</el-button>-->
      <el-button type="primary" size="mini" style="margin-left: 10px" @click="init()">重载模型</el-button>
    </div>
    <div class="state-list">
      <div v-for="schedule in scheduleList" :key="schedule.name" class="state-item" :style="{color: schedule.color}"><span :style="{ backgroundColor: schedule.bgColor }" /><span>{{ schedule.name }}</span></div>
    </div>
    <div id="view" />
    <div @click="showBarHandler" class="show-vedio-list" :class="showBar ? 'btn-right-move' : 'btn-left-move'">
      <i v-if="showBar" class="el-icon-arrow-right" />
      <i v-else class="el-icon-arrow-left" />
    </div>
    <transition name="move">
      <div class="bar-area" v-if="showBar">
        <schedule-bar :floor-total="floors.length" :schedule-list="scheduleList" ref="scheduleBarRef" />
      </div>
    </transition>
    <el-dialog title="验收列表" :visible.sync="showInfo" width="70%">
      <div class="check-list" v-if="showInfo">
        <check-list />
      </div>
    </el-dialog>
  </div>
</template>

<script>
/* eslint-disable */
import axios from 'axios'
import { buildingList } from '@/api/common'
import scheduleBar from './components/scheduleBar'
import CheckList from '@/views/statement/CheckList'
import HeaderSelect from '@/views/statement/components/HeaderSelect'
import {  stateIcon,
   floorViewTokens, viewTokenFloorUrl,
  camera, scheduleList, scheduleDetail} from './bimData'
import { getBuildingView } from '@/api/statement/processSchedule'
let app = null
let viewer3D = null
let model3D = null

export default {
  name: 'BimBuildingView',
  data() {
    return {
      floorName: '',
      bimObjData: {},
      scheduleList: [],
      showInfo: false,
      detail: scheduleDetail[0],
      viewTokenIndex: 0,
      viewToken: '',
      floorViewTokens: floorViewTokens,
      sessionFloorViewTokens: [],
      floorList: [], // 获取模型楼层信息
      camera: {},
      showBar: false,
      detailStyle: {left: '10px'},
      floors: [],
      loading: false,
      buildings: [],
      buildingId: '',
      checkTableIds: [] // 工序ID数组
    }
  },
  components: { scheduleBar, CheckList, HeaderSelect },

  mounted() { // 初始化
    const sessionTokens = sessionStorage.getItem('sessionFloorViewTokens')
    if (sessionTokens) {
      this.sessionFloorViewTokens = JSON.parse(sessionTokens)
      this.sessionFloorViewTokens.forEach((token,index) => {
        if (token) {
          floorViewTokens.splice(index, 1, token)
        }
      })
    } else {
      this.sessionFloorViewTokens = new Array(floorViewTokens.length)
    }
    this.checkTableIds = scheduleList.map(schedule => schedule.checkTableId)
    this.viewToken = floorViewTokens[this.viewTokenIndex]
    // this.getBuildingsByPro('+aWTsJouRnKUfm2WN8kIK/nl6Ss=')
    // this.getContentData(this.buildingId, this.checkTableIds)
  },

  beforeDestroy() {
    if (app) {
      app.destroy()
      app = null
    }
  },
  methods: {
    getProject(project) {
      this.getBuildingsByPro(project.id)
    },
    /** 根据项目ID获取楼栋 */
    getBuildingsByPro(projectId) {
      buildingList({ projectId }).then((response) => {
        this.buildings = response.data
        if (response.data && response.data.length > 0) {
          this.buildingId = response.data[0].id
          this.getContentData(this.buildingId, this.checkTableIds)
        } else {
          this.buildingId = ''
          this.buildings = []
          this.$message.info('当前项目不存在楼栋')
        }
      })
    },
    // 切换楼栋
    selectBuilding() {
      this.getContentData(this.buildingId, this.checkTableIds)
    },
    /**
     * 查询楼栋视图数据
     * @param buildingId 楼栋ID
     * @param processIds 工序Ids
     * @param roleKey 角色key
     */
    getContentData(buildingId, processIds = []) {
      const scheduleListCopy = JSON.parse(JSON.stringify(scheduleList))
      if (!buildingId || this.loading) {
        return
      }
      this.loading = true
      getBuildingView({ buildingId: buildingId, checkTableId: processIds.join(',') }).then(res => {
        const data = res.data
        if (data.floor) {
          const content = data.content || []
          this.floors = data.floor || []
          for (let i = 0; i < scheduleListCopy.length; i++){
            for (let j = 0; j < content.length; j++) {
              if (scheduleListCopy[i].checkTableId === content[j].checkTableId) {
                if (content[j].table && content[j].table.length > 0) {
                  const table = content[j].table
                  let floorChecked = [] // 通过验收楼层
                  for (let z = 0; z < table.length; z++) {
                    if (content[j].unitType === 1) { // 验收对象楼层
                      if (table[z].status === 10) {
                        floorChecked.push(table[z].objectId)
                      }
                    } else if (content[j].unitType === 2) { // 验收对象房间
                      if (table[z].some(room => room.status === 10)) {
                        const name = table[z][0].name
                        floorChecked.push(name.substr(0, (name.length - 2)))
                      }
                    }
                  }
                  scheduleListCopy[i].floorList = floorChecked
                  if (floorChecked.length > 0) {
                    scheduleListCopy[i].value = parseInt(floorChecked[0])
                    scheduleListCopy[i].floor = 'F' + floorChecked[0]
                  } else {
                    scheduleListCopy[i].value = 0
                    scheduleListCopy[i].floor = ''
                  }
                }
              }
            }
          }
          this.scheduleList = scheduleListCopy.sort((obj1, obj2) => {
            return obj2.value - obj1.value
          })
          this.showBarHandler()
          this.init()
        } else {
          this.$message.info('当前楼栋不存在对应验收楼层信息。')
        }
      }).finally(() => {
        this.loading = false
      })
    },
    // 楼层操作
    getFloors() {
      viewer3D.getFloors((data) => {
        this.floorList = data
        // 进度渲染
        this.scheduleRender()
      });
    },
    showInfoHandler(obj) {
      if (obj && obj.objectId) {
        const objectData = model3D.getObjectDataById(obj.objectId)
        const floor = objectData.levelName
        let checktableId = ''
        let objectId = floor.substr(1, floor.length - 1)
        if (floor) {
          for (let i = 0; i < this.scheduleList.length; i++) {
            if (floor === this.scheduleList[i].floor) {
              checktableId = this.scheduleList[i].checkTableId
              if (this.scheduleList[i].unitType === 1) { // 验收对象楼层
                this.$router.replace({query: {buildingId: this.buildingId, checktableId: checktableId, objectId: objectId}})
                this.showInfo = true
              } else if (this.scheduleList[i].unitType === 2) {
                this.$message.info('当前工序验收对象为房间，BIM模型未设置相应房间。')
              }
            }
          }
          if (!checktableId) { // 未匹配到楼层，匹配验收所有楼层
            for (let i = this.scheduleList.length - 1; i >= 0; i--) {
              const floorList = this.scheduleList[i].floorList
              for (let j = 0; j < floorList.length; j++) {
                if (floorList[j] === objectId) {
                  checktableId = this.scheduleList[i].checkTableId
                  if (this.scheduleList[i].unitType === 1) { // 验收对象楼层
                    this.$router.replace({query: {buildingId: this.buildingId, checktableId: checktableId, objectId: objectId}})
                    this.showInfo = true
                  } else if (this.scheduleList[i].unitType === 2) {
                    this.$message.info('当前工序验收对象为房间，BIM模型未设置相应房间。')
                  }
                }
              }
            }
          }
        }
      } else {
        this.showInfo = false
      }
      viewer3D.clearSelectedComponents()
    },
    floorChange() {
      model3D.clearOverrideColorComponents()
      if (this.floorName) {
        const conditions = [
          { levelName: this.floorName }
        ]
        const originalColor = colourBlend('#4b50d3', '#61d35c', 0.5)
        //定义颜色
        let color = new Glodon.Web.Graphics.Color(originalColor, 0.5)
        //根据条件对构件线框着色
        model3D.overrideComponentsColorByObjectData(conditions, color)
        // 组件隔离
        const state = Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent
        model3D.isolateComponentsByObjectData(conditions, state)
        viewer3D.render()
      }
    },
    // 进度渲染
    scheduleRender() {
      if (this.scheduleList && this.scheduleList.length === 0 && !model3D) return
      let allConditions = [] // 模型可搜索楼层 条件
      this.floorList.forEach(floor => {
        allConditions.push({levelName: floor.name})
      })

      let allCheckedFloor = [] // 所有已验收楼层

      for (let i = 0; i < this.scheduleList.length; i++) {
        allCheckedFloor.push(...this.scheduleList[i].floorList)
        let conditions = []
        for (let j = 0; j < allConditions.length; j++) {
          if (this.scheduleList[i].floorList.some(floor => allConditions[j].levelName === `F${floor}`)) {
            conditions.push({...allConditions[j]})
          }
        }
        //定义颜色
        let color = new Glodon.Web.Graphics.Color(this.scheduleList[i].color, 0.5)
        //根据条件对构件线框着色
        model3D.overrideComponentsColorByObjectData(conditions, color)
      }
      allCheckedFloor = Array.from(new Set(allCheckedFloor)) // 去重
      // 隔离楼层
      let isolateCoditions = []
      for (let j = 0; j < allConditions.length; j++) {
        if (allCheckedFloor.some(checkedFloor => `F${checkedFloor}` === allConditions[j].levelName)) {
          isolateCoditions.push({...allConditions[j]})
        }
      }
      // 组件隔离
      const state = Glodon.Bimface.Viewer.IsolateOption.MakeOthersTranslucent
      model3D.isolateComponentsByObjectData(isolateCoditions, state)
      viewer3D.render()
    },
    init () {
      this.initBIMFace()
    },
    viewTokenInput() {
      floorViewTokens.splice(this.viewTokenIndex, 1, this.viewToken)
      this.sessionFloorViewTokens.splice(this.viewTokenIndex, 1, this.viewToken)
      sessionStorage.setItem('sessionFloorViewTokens', JSON.stringify(this.sessionFloorViewTokens))
      this.initBIMFace()
    },
    switchModel() {
      this.viewTokenIndex += 1
      if (this.viewTokenIndex >= floorViewTokens.length) {
        this.viewTokenIndex = 0
      }
      this.viewToken = floorViewTokens[this.viewTokenIndex]
      this.initBIMFace()
    },
    viewer3DResize() {
      this.$nextTick(() => {
        const elementDom = document.getElementById('view')
        viewer3D.resize(elementDom.offsetWidth, elementDom.offsetWidth)
      })
    },

    // bim 模型初始化
    initBIMFace() {
      const self = this
      if (!self.viewToken) return
      if (app) {
        app.destroy()
        app = null
      }
      // 创建BimfaceSDKLoaderConfig
      const loaderConfig = new BimfaceSDKLoaderConfig()
      // 设置BimfaceSDKLoaderConfig的viewToken
      loaderConfig.viewToken = self.viewToken
      // 调用BimfaceSDKLoader的load方法加载模型
      BimfaceSDKLoader.load(loaderConfig, successCallback, failureCallback)
      // 加载成功回调函数
      function successCallback(viewMetaData) {
        // 获取DOM元素
        const domShow = document.getElementById('view')
        // 创建WebApplication3DConfig
        const webAppConfig = new Glodon.Bimface.Application.WebApplication3DConfig()
        // 设置创建WebApplication3DConfig的dom元素值
        webAppConfig.domElement = domShow
        // 创建WebApplication3D
        app = new Glodon.Bimface.Application.WebApplication3D(webAppConfig)
        // 添加待显示的模型
        app.addView(self.viewToken)
        // 获取viewer3D对象
        viewer3D = app.getViewer()
        // 设置主视图
        viewer3D.recordCustomHomeview(camera)
        // 渐变3d背景色
        const color1 = new Glodon.Web.Graphics.Color('#001321', 1)
        const color2 = new Glodon.Web.Graphics.Color('#00273C', 0.7)
        viewer3D.setBackgroundColor(color1)
        // 添加点击监听事件，创建三维标签
        viewer3D.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.MouseClicked, self.showInfoHandler);
        viewer3D.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ModelAdded, function (data) {
          // 从viewer3D对象中获取模型对象model3D
          const model3D = viewer3D.getModel(data)
          // model3D.setModelScale({ x: 0, y: 0, z: 0 }, 2);
          viewer3D.render()
        })

        // 场景加载完成触发
        viewer3D.addEventListener(Glodon.Bimface.Viewer.Viewer3DEvent.ViewAdded, function () {
          model3D = viewer3D.getModel()
          self.getFloors()
          if (!self.showBar) {
            self.showBarHandler()
          }
          // 设置相机位置
          viewer3D.setCameraStatus(camera)
          viewer3D.render()
        })
      }

      // 加载失败回调函数
      function failureCallback(error) {
        self.$confirm('模型viewToken过期，请重新获取viewToken,并输入新viewToken。', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          self.viewToken = ''
          window.open(viewTokenFloorUrl[self.viewTokenIndex], '_blank');
        }).catch(() => {

        });
      }
    },
    showBarHandler() {
      if (this.scheduleList && this.scheduleList.length > 0 && this.scheduleList.some(schedule => schedule.floorList.length > 0)) {
        this.showBar = !this.showBar
        if (this.showBar) {
          this.$nextTick(() => {
            this.$refs.scheduleBarRef.init()
          })
        }
      } else {
        this.showBar = false
        this.$message.info('当前楼栋暂无BIM相关工序验收数据。')
      }
    },
  }
}
</script>

<style scoped lang='scss'>
  #view {
    height: calc(100% - 50px);
    text-align: left;
    position: relative;
    background-color: #00080e;
  }
  .show-vedio-list {
    position: absolute;
    right: 510px;
    top: 300px;
    z-index: 1;
    width: 10px;
    background-color: rgba(78, 216, 248, 0.5);
    height: 40px;
    line-height: 40px;
    border-radius: 5px 0 0 5px;
    cursor: pointer;
    i {
      font-size: 12px;
      color: #ffffff;
    }
  }
  .bar-area {
    width: 500px;
    position: absolute;
    right: 10px;
    top: 100px;
  }
  .state-list {
    font-size: 12px;
    display: flex;
    background-color: #001321;
    padding-top: 10px;
    justify-content: center;
    .state-item {
      height: 26px;
      margin-left: 20px;
      span:nth-child(1) {
        display: inline-block;
        height: 10px;
        width: 10px;
        border-radius: 50%;
        margin-right: 10px;
      }
    }
  }
  .bim-operation {
    display: flex;
    align-items: center;
    margin: 10px;
    .custom-select {
      width: 300px;
      margin-left: 10px;
    }
    .select-label {

    }
  }
  .check-list {
    min-height: 300px;
    max-height: 75vh;
    overflow-y: auto;
  }
  .move-enter-active {
    animation: moveEnter 0.5s linear;
  }
  .move-leave-active{
    animation: moveLeave 0.5s linear;
  }
  @keyframes moveEnter {
    from{
      transform: translateX(100%);
    }
    to{
      transform: translateX(0px);
    }
  }
  @keyframes moveLeave {
    from{
      transform: translateX(0px);
    }
    to{
      transform: translateX(100%);
    }
  }
  .btn-right-move {
    animation: rightMove 0.5s linear forwards;
  }
  .btn-left-move {
    animation: leftMove 0.5s linear forwards;
  }
  @keyframes rightMove {
    from{
      transform: translateX(510px);
    }
    to{
      transform: translateX(0px);
    }
  }
  @keyframes leftMove {
    from{
      transform: translateX(0px);
    }
    to{
      transform: translateX(510px);
    }
  }
</style>
